/*
 *  Copyright (C) 2010 Glauco
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.balisunrise.common;

import java.util.Properties;

/**
 * Está interface disponibiliza métodos para construir e utilizar componentes
 * de tela (Representaão Visual) a partir de um atributo(<code>Field</code>)
 * de uma entidade.
 * @author Glauco
 * @param <T> Classe que Representa o tipo de dado do atributo de uma entidade.
 * @param <J> O Tipo do Componente de tela criado e utilizado para representar
 * visualmente o atributo de uma entidade.
 */
public interface ComponentManager<T,J> {

    /**
     * Retorna a Classe do dado tipo de dado de um atributo de uma entidade.
     * @return Class que o componente visual representa.
     */
    public Class<T> getType();

    /**
     * Retorna a Classe do componente visual
     * @return Class do componente visual.
     */
    public Class<J> getComponentType();

    /**
     * Constroi a representação visual de um tipo de dado.
     * @param componentName nome para o componente.
     * @param p propriedades do componente.
     * @return Um novo componente visual.
     */
    public J buildComponent(Properties p);

    /**
     * Limpa o valor do compente.
     * @param component que deve ser limpo o seu valo.
     */
    public void clearComponentValue(J component);

    /**
     * Le o valor do componente. O valor não tem uma classe fixa, depende do
     * tipo de componente.
     * @param component componente que deve ser extraido o seu valor.
     * @return Objeto representando o valor do componente.
     */
    public Object readValue(J component);

    /**
     * Le o valor do componente convertido para o mesmo tipo de dado que o
     * atributo da entidade.
     * @param component componente que deve ser extraido o seu valor.
     * @param nullForEmpty retorna nulo quando valor for vazio.
     * @return Objeto do tipo de dado do atributo de uma entidade.
     */
    public T readConvertedValue(J component, boolean nullForEmpty)
            throws ConverterException;

    /**
     * Atribui o valor da propriedade de uma entidade ao componente.
     * O valor será convertido utilizando o Converter.
     * @param propertyValue Valor de uma propriedade da entidade.
     * @param component Componente a receber o valor
     * @throws ComponentConverterException caso ocorra alguma erro na atribuição
     */
    public void insertValue(T propertyValue, J component)
            throws ConverterException;

    /**
     * Atribui o valor da propriedade de uma entidade ao componente.
     * @param propertyValue Valor de uma propriedade da entidade.
     * @param component Componente a receber o valor
     */
    public void insertConvertedValue(Object propertyValue,
            J component);

    /**
     * Retorna o conversor para o tipo de dado do ComponentManager.
     * @return Converter
     */
    public Converter<T,? extends Object> getConverter(boolean nullForEmpty);

    /**
     * Cria um vinculo do atributo do source para um atributo do componente e
     * adiciona ao grupo de vinculos.
     * @param bindingGroup Grupo de vinculos.
     * @param source objeto source.
     * @param property atributo do source a ser vinculado.
     * @param component componente target
     * @param nullForEmpty Flag para converter o valor vazio para nulo.
     * @param owner Basic proprietário do componente.
     * @return O Binding criado, já adicionado ao BindingGroup.
     */
    public Binding createBinding(BindingGroup bindingGroup,
            Object source, String property, J component,
            boolean nullForEmpty, Basic owner);
}
